using System;

namespace Be.Timvw.Framework
{
    /// <summary>
    /// This class contains helper methods for the manipulation of DateTime instances.
    /// </summary>
    public static class DateTimeHelper
    {
        /// <summary>
        /// The base DateTime.
        /// </summary>
        public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);

        /// <summary>
        /// Converts a unixtime into a DateTime.
        /// </summary>
        /// <param name="timestamp">The unixtime to convert.</param>
        /// <returns>An equivalent datetime for the given unixtime.</returns>
        public static DateTime FromUnixTime(double timestamp)
        {
            return UnixEpoch.AddSeconds(timestamp);
        }

        /// <summary>
        /// Converts a DateTime to a unixtime.
        /// </summary>
        /// <param name="dateTime">The datetime to convert.</param>
        /// <returns>An equivalent unixtime for the given datetime.</returns>
        public static double ToUnixTime(DateTime dateTime)
        {
            TimeSpan timeSpan = dateTime - UnixEpoch;
            return timeSpan.TotalSeconds;
        }

        /// <summary>
        /// Returns the first day of the week for a given datetime.
        /// </summary>
        /// <param name="dateTime">The given datetime.</param>
        /// <returns>The first day of the week.</returns>
        public static DateTime FirstDayOfWeek(DateTime dateTime)
        {
            if(dateTime.DayOfWeek == DayOfWeek.Sunday)
            {
                dateTime = dateTime.AddDays(-7);
            }
            return dateTime.AddDays(-Convert.ToInt32(dateTime.DayOfWeek) + 1);
        }

        /// <summary>
        /// Returns the last day of the week for a given datetime.
        /// </summary>
        /// <param name="dateTime">The given datetime.</param>
        /// <returns>The last day of the week.</returns>
        public static DateTime LastDayOfWeek(DateTime dateTime)
        {
            if(dateTime.DayOfWeek == DayOfWeek.Sunday)
            {
                dateTime = dateTime.AddDays(-7);
            }
            return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day).AddDays(7 - Convert.ToInt32(dateTime.DayOfWeek));
        }

        /// <summary>
        /// Returns the first day of the month of a given datetime.
        /// </summary>
        /// <param name="dateTime">The given datetime.</param>
        /// <returns>The first day of the month.</returns>
        public static DateTime FirstDayOfMonth(DateTime dateTime)
        {
            return new DateTime(dateTime.Year, dateTime.Month, 1);
        }

        /// <summary>
        /// Returns the last day of the month for a given datetme.
        /// </summary>
        /// <param name="dateTime">The given datetime.</param>
        /// <returns>The last day of the month.</returns>
        public static DateTime LastDayOfMonth(DateTime dateTime)
        {
            return new DateTime(dateTime.Year, dateTime.Month, DateTime.DaysInMonth(dateTime.Year, dateTime.Month));
        }
    }
}